#include "p2pprotocol.hpp"

int EnCodeLoginReq(void* pHost, CNetData* poNetData)
{
	LoginReq* pstIn = (LoginReq*)pHost;

	if(-1==poNetData->AddWord(pstIn->moudleid))
		return -1;

	if(-1==poNetData->AddWord(pstIn->protocolid))
		return -1;

	if(-1 == poNetData->AddDword(pstIn->local_ip))
		return -1;

	if(-1 == poNetData->AddWord(pstIn->local_port))
		return -1;

	return poNetData->GetDataLen();
}
int DeCodeLoginReq(void* pHost, CNetData* poNetData)
{
	LoginReq* pstOut = (LoginReq*)pHost;

	if(-1==poNetData->DelWord((unsigned short)pstOut->moudleid))
		return -1;

	if(-1==poNetData->DelWord((unsigned short)pstOut->protocolid))
		return -1;

	if(-1 == poNetData->DelDword(pstOut->local_ip))
		return -1;

	if(-1 == poNetData->DelWord(pstOut->local_port))
		return -1;

	return sizeof(*pstOut);
}
int EnCodeLoginAck(void* pHost, CNetData* poNetData)
{
	LoginAck* pstIn = (LoginAck*)pHost;

	if(-1==poNetData->AddWord(pstIn->moudleid))
		return -1;

	if(-1==poNetData->AddWord(pstIn->protocolid))
		return -1;

	if(-1 == poNetData->AddDword(pstIn->err_code))
		return -1;

	if(-1 == poNetData->AddDword(pstIn->p2p_id))
		return -1;

	if(-1 == poNetData->AddDword(pstIn->rand_key))
		return -1;

	if(-1 == poNetData->AddDword(pstIn->public_ip))
		return -1;

	if(-1 == poNetData->AddWord(pstIn->public_port))
		return -1;

	return poNetData->GetDataLen();
}
int DeCodeLoginAck(void* pHost, CNetData* poNetData)
{
	LoginAck* pstOut = (LoginAck*)pHost;

	if(-1==poNetData->DelWord((unsigned short)pstOut->moudleid))
		return -1;

	if(-1==poNetData->DelWord((unsigned short)pstOut->protocolid))
		return -1;

	if(-1 == poNetData->DelDword(pstOut->err_code))
		return -1;

	if(-1 == poNetData->DelDword(pstOut->p2p_id))
		return -1;

	if(-1 == poNetData->DelDword(pstOut->rand_key))
		return -1;

	if(-1 == poNetData->DelDword(pstOut->public_ip))
		return -1;

	if(-1 == poNetData->DelWord(pstOut->public_port))
		return -1;

	return sizeof(*pstOut);
}
int EnCodeNATTestReq(void* pHost, CNetData* poNetData)
{
	NATTestReq* pstIn = (NATTestReq*)pHost;

	if(-1==poNetData->AddWord(pstIn->moudleid))
		return -1;

	if(-1==poNetData->AddWord(pstIn->protocolid))
		return -1;

	if(-1 == poNetData->AddDword(pstIn->p2p_id))
		return -1;

	if(-1 == poNetData->AddDword(pstIn->local_ip))
		return -1;

	if(-1 == poNetData->AddWord(pstIn->local_port))
		return -1;

	if(-1 == poNetData->AddDword(pstIn->rand_key))
		return -1;

	return poNetData->GetDataLen();
}
int DeCodeNATTestReq(void* pHost, CNetData* poNetData)
{
	NATTestReq* pstOut = (NATTestReq*)pHost;

	if(-1==poNetData->DelWord((unsigned short)pstOut->moudleid))
		return -1;

	if(-1==poNetData->DelWord((unsigned short)pstOut->protocolid))
		return -1;

	if(-1 == poNetData->DelDword(pstOut->p2p_id))
		return -1;

	if(-1 == poNetData->DelDword(pstOut->local_ip))
		return -1;

	if(-1 == poNetData->DelWord(pstOut->local_port))
		return -1;

	if(-1 == poNetData->DelDword(pstOut->rand_key))
		return -1;

	return sizeof(*pstOut);
}
int EnCodeNATTestAck(void* pHost, CNetData* poNetData)
{
	NATTestAck* pstIn = (NATTestAck*)pHost;

	if(-1==poNetData->AddWord(pstIn->moudleid))
		return -1;

	if(-1==poNetData->AddWord(pstIn->protocolid))
		return -1;

	if(-1 == poNetData->AddByte(pstIn->nat_type))
		return -1;

	return poNetData->GetDataLen();
}
int DeCodeNATTestAck(void* pHost, CNetData* poNetData)
{
	NATTestAck* pstOut = (NATTestAck*)pHost;

	if(-1==poNetData->DelWord((unsigned short)pstOut->moudleid))
		return -1;

	if(-1==poNetData->DelWord((unsigned short)pstOut->protocolid))
		return -1;

	if(-1 == poNetData->DelByte(pstOut->nat_type))
		return -1;

	return sizeof(*pstOut);
}
int EnCodeKeepAlive(void* pHost, CNetData* poNetData)
{
	KeepAlive* pstIn = (KeepAlive*)pHost;

	if(-1==poNetData->AddWord(pstIn->moudleid))
		return -1;

	if(-1==poNetData->AddWord(pstIn->protocolid))
		return -1;

	return poNetData->GetDataLen();
}
int DeCodeKeepAlive(void* pHost, CNetData* poNetData)
{
	KeepAlive* pstOut = (KeepAlive*)pHost;

	if(-1==poNetData->DelWord((unsigned short)pstOut->moudleid))
		return -1;

	if(-1==poNetData->DelWord((unsigned short)pstOut->protocolid))
		return -1;

	return sizeof(*pstOut);
}
int EnCodeConnectPeerReq(void* pHost, CNetData* poNetData)
{
	ConnectPeerReq* pstIn = (ConnectPeerReq*)pHost;

	if(-1==poNetData->AddWord(pstIn->moudleid))
		return -1;

	if(-1==poNetData->AddWord(pstIn->protocolid))
		return -1;

	if(-1 == poNetData->AddDword(pstIn->dst_p2p_id))
		return -1;

	return poNetData->GetDataLen();
}
int DeCodeConnectPeerReq(void* pHost, CNetData* poNetData)
{
	ConnectPeerReq* pstOut = (ConnectPeerReq*)pHost;

	if(-1==poNetData->DelWord((unsigned short)pstOut->moudleid))
		return -1;

	if(-1==poNetData->DelWord((unsigned short)pstOut->protocolid))
		return -1;

	if(-1 == poNetData->DelDword(pstOut->dst_p2p_id))
		return -1;

	return sizeof(*pstOut);
}
int EnCodeConnectPeerAck(void* pHost, CNetData* poNetData)
{
	ConnectPeerAck* pstIn = (ConnectPeerAck*)pHost;

	if(-1==poNetData->AddWord(pstIn->moudleid))
		return -1;

	if(-1==poNetData->AddWord(pstIn->protocolid))
		return -1;

	if(-1 == poNetData->AddDword(pstIn->dst_p2p_id))
		return -1;

	if(-1 == poNetData->AddByte(pstIn->dst_nat_type))
		return -1;

	if(-1 == poNetData->AddDword(pstIn->dst_public_ip))
		return -1;

	if(-1 == poNetData->AddWord(pstIn->dst_public_port))
		return -1;

	if(-1 == poNetData->AddDword(pstIn->dst_private_ip))
		return -1;

	if(-1 == poNetData->AddWord(pstIn->dst_private_port))
		return -1;

	return poNetData->GetDataLen();
}
int DeCodeConnectPeerAck(void* pHost, CNetData* poNetData)
{
	ConnectPeerAck* pstOut = (ConnectPeerAck*)pHost;

	if(-1==poNetData->DelWord((unsigned short)pstOut->moudleid))
		return -1;

	if(-1==poNetData->DelWord((unsigned short)pstOut->protocolid))
		return -1;

	if(-1 == poNetData->DelDword(pstOut->dst_p2p_id))
		return -1;

	if(-1 == poNetData->DelByte(pstOut->dst_nat_type))
		return -1;

	if(-1 == poNetData->DelDword(pstOut->dst_public_ip))
		return -1;

	if(-1 == poNetData->DelWord(pstOut->dst_public_port))
		return -1;

	if(-1 == poNetData->DelDword(pstOut->dst_private_ip))
		return -1;

	if(-1 == poNetData->DelWord(pstOut->dst_private_port))
		return -1;

	return sizeof(*pstOut);
}
int EnCodePeerConnectReq(void* pHost, CNetData* poNetData)
{
	PeerConnectReq* pstIn = (PeerConnectReq*)pHost;

	if(-1==poNetData->AddWord(pstIn->moudleid))
		return -1;

	if(-1==poNetData->AddWord(pstIn->protocolid))
		return -1;

	if(-1 == poNetData->AddDword(pstIn->peer_p2p_id))
		return -1;

	if(-1 == poNetData->AddByte(pstIn->peer_nat_type))
		return -1;

	if(-1 == poNetData->AddDword(pstIn->peer_public_ip))
		return -1;

	if(-1 == poNetData->AddWord(pstIn->peer_public_port))
		return -1;

	if(-1 == poNetData->AddDword(pstIn->peer_private_ip))
		return -1;

	if(-1 == poNetData->AddWord(pstIn->peer_private_port))
		return -1;

	return poNetData->GetDataLen();
}
int DeCodePeerConnectReq(void* pHost, CNetData* poNetData)
{
	PeerConnectReq* pstOut = (PeerConnectReq*)pHost;

	if(-1==poNetData->DelWord((unsigned short)pstOut->moudleid))
		return -1;

	if(-1==poNetData->DelWord((unsigned short)pstOut->protocolid))
		return -1;

	if(-1 == poNetData->DelDword(pstOut->peer_p2p_id))
		return -1;

	if(-1 == poNetData->DelByte(pstOut->peer_nat_type))
		return -1;

	if(-1 == poNetData->DelDword(pstOut->peer_public_ip))
		return -1;

	if(-1 == poNetData->DelWord(pstOut->peer_public_port))
		return -1;

	if(-1 == poNetData->DelDword(pstOut->peer_private_ip))
		return -1;

	if(-1 == poNetData->DelWord(pstOut->peer_private_port))
		return -1;

	return sizeof(*pstOut);
}
int EnCodeP2PHandleReq(void* pHost, CNetData* poNetData)
{
	P2PHandleReq* pstIn = (P2PHandleReq*)pHost;

	if(-1==poNetData->AddWord(pstIn->moudleid))
		return -1;

	if(-1==poNetData->AddWord(pstIn->protocolid))
		return -1;

	if(-1 == poNetData->AddDword(pstIn->my_p2p_id))
		return -1;

	return poNetData->GetDataLen();
}
int DeCodeP2PHandleReq(void* pHost, CNetData* poNetData)
{
	P2PHandleReq* pstOut = (P2PHandleReq*)pHost;

	if(-1==poNetData->DelWord((unsigned short)pstOut->moudleid))
		return -1;

	if(-1==poNetData->DelWord((unsigned short)pstOut->protocolid))
		return -1;

	if(-1 == poNetData->DelDword(pstOut->my_p2p_id))
		return -1;

	return sizeof(*pstOut);
}
int EnCodeP2PHandleAck(void* pHost, CNetData* poNetData)
{
	P2PHandleAck* pstIn = (P2PHandleAck*)pHost;

	if(-1==poNetData->AddWord(pstIn->moudleid))
		return -1;

	if(-1==poNetData->AddWord(pstIn->protocolid))
		return -1;

	if(-1 == poNetData->AddDword(pstIn->my_p2p_id))
		return -1;

	return poNetData->GetDataLen();
}
int DeCodeP2PHandleAck(void* pHost, CNetData* poNetData)
{
	P2PHandleAck* pstOut = (P2PHandleAck*)pHost;

	if(-1==poNetData->DelWord((unsigned short)pstOut->moudleid))
		return -1;

	if(-1==poNetData->DelWord((unsigned short)pstOut->protocolid))
		return -1;

	if(-1 == poNetData->DelDword(pstOut->my_p2p_id))
		return -1;

	return sizeof(*pstOut);
}
Cp2pprotocol::Cp2pprotocol()
{
	m_EnCodeFuncArray[0] = &EnCodeLoginReq;
	m_DeCodeFuncArray[0] = &DeCodeLoginReq;

	m_EnCodeFuncArray[1] = &EnCodeLoginAck;
	m_DeCodeFuncArray[1] = &DeCodeLoginAck;

	m_EnCodeFuncArray[2] = &EnCodeNATTestReq;
	m_DeCodeFuncArray[2] = &DeCodeNATTestReq;

	m_EnCodeFuncArray[3] = &EnCodeNATTestAck;
	m_DeCodeFuncArray[3] = &DeCodeNATTestAck;

	m_EnCodeFuncArray[4] = &EnCodeKeepAlive;
	m_DeCodeFuncArray[4] = &DeCodeKeepAlive;

	m_EnCodeFuncArray[5] = &EnCodeConnectPeerReq;
	m_DeCodeFuncArray[5] = &DeCodeConnectPeerReq;

	m_EnCodeFuncArray[6] = &EnCodeConnectPeerAck;
	m_DeCodeFuncArray[6] = &DeCodeConnectPeerAck;

	m_EnCodeFuncArray[7] = &EnCodePeerConnectReq;
	m_DeCodeFuncArray[7] = &DeCodePeerConnectReq;

	m_EnCodeFuncArray[8] = &EnCodeP2PHandleReq;
	m_DeCodeFuncArray[8] = &DeCodeP2PHandleReq;

	m_EnCodeFuncArray[9] = &EnCodeP2PHandleAck;
	m_DeCodeFuncArray[9] = &DeCodeP2PHandleAck;

}

Cp2pprotocol::~Cp2pprotocol()
{
}

int Cp2pprotocol::BuildProtocol(void* pHost, char *pNet, int iNetSize)
{
	CNetData m_oData;
	m_oData.Prepare(pNet, iNetSize);
	if (*(unsigned short*)pHost != 1)
	{
		return -1;
	}
	if (*(unsigned short*)((char*)pHost+sizeof(unsigned short)) >= sizeof(m_EnCodeFuncArray)/sizeof(EnCodeFuncp2pprotocol))
	{
		return -1;
	}
	return m_EnCodeFuncArray[*(unsigned short*)((char*)pHost+sizeof(unsigned short))](pHost, &m_oData);
}

bool Cp2pprotocol::HandleProtocol(char *pNet, int iNetSize, void* pHost)
{
	CNetData m_oData;
	m_oData.Prepare(pNet, iNetSize);

	unsigned short moudleid = 0;
	unsigned short protocolid = 0;
	if (m_oData.DelWord(moudleid) < 0)
	{
		return false;
	}
	if (moudleid != 1)
	{
		return false;
	}
	if (m_oData.DelWord(protocolid) < 0)
	{
		return false;
	}
	if (protocolid >= sizeof(m_DeCodeFuncArray)/sizeof(DeCodeFuncp2pprotocol))
	{
		return false;
	}

	m_oData.Prepare(pNet, iNetSize);

	if (m_DeCodeFuncArray[protocolid](pHost, &m_oData) < 0)
	{
		return false;
	}

	switch(protocolid)
	{
	case 0:
		OnRecv_LoginReq(*(LoginReq*)pHost);
		break;
	case 1:
		OnRecv_LoginAck(*(LoginAck*)pHost);
		break;
	case 2:
		OnRecv_NATTestReq(*(NATTestReq*)pHost);
		break;
	case 3:
		OnRecv_NATTestAck(*(NATTestAck*)pHost);
		break;
	case 4:
		OnRecv_KeepAlive(*(KeepAlive*)pHost);
		break;
	case 5:
		OnRecv_ConnectPeerReq(*(ConnectPeerReq*)pHost);
		break;
	case 6:
		OnRecv_ConnectPeerAck(*(ConnectPeerAck*)pHost);
		break;
	case 7:
		OnRecv_PeerConnectReq(*(PeerConnectReq*)pHost);
		break;
	case 8:
		OnRecv_P2PHandleReq(*(P2PHandleReq*)pHost);
		break;
	case 9:
		OnRecv_P2PHandleAck(*(P2PHandleAck*)pHost);
		break;
	default:
		return false;
	}

	return true;
}

